package com.hx.setting.utils;

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;

/**
 * Generate Date : 2014-03-16
 * Generate Version : v3.0
 * Generate Name : Honey v3.1 Test
 * Generate User : THINK
 * JDK Version : 1.5
 */
public final class ImageUtils
{

	/** 
	 * 旋转 因为旋转后造成图像缺失，在旋转前需要平移一段距离
	 * 
	 * @param image
	 * 原图
	 * @param angle
	 * 旋转角度
	 * @param color
	 * 无图像部分的填充色,默认值为{255,255,255}
	 * @return
	 */
	public static BufferedImage rotate(BufferedImage image, Double angle, Integer[] color)
	{
		int width = image.getWidth();
		int height = image.getHeight();
		angle = (360 - angle);
		// 无图像部分填充的颜色默认值
		if ( color == null )
		{
			Integer[] tempColors =
			{ 0, 0, 0 };
			color = tempColors;
		}
		// 需要平移的距离
		double _x;
		double _y;
		if ( angle <= 90 )
		{
			_x = 0;
			_y = (width * Math.sin( angle / 180 * Math.PI ));
		}
		else if ( angle <= 180 )
		{
			_x = (width * Math.cos( angle / 180 * Math.PI )) * (-1);
			_y = (width * Math.sin( angle / 180 * Math.PI ) - height * Math.cos( angle / 180 * Math.PI ));
		}
		else if ( angle <= 270 )
		{
			_x = (width * Math.cos( angle / 180 * Math.PI ) + height * Math.sin( angle / 180 * Math.PI )) * (-1);
			_y = (height * Math.cos( angle / 180 * Math.PI )) * (-1);
		}
		else
		{
			_x = (height * Math.sin( angle / 180 * Math.PI )) * (-1);
			_y = 0;
		}
		// 旋转后的图像大小
		int _w = (int) Math.round( width * Math.abs( Math.cos( angle / 180 * Math.PI ) ) + height * Math.abs( Math.sin( angle / 180 * Math.PI ) ) );
		int _h = (int) Math.round( width * Math.abs( Math.sin( angle / 180 * Math.PI ) ) + height * Math.abs( Math.cos( angle / 180 * Math.PI ) ) );
		// 平移图像
		AffineTransform affineTransform = AffineTransform.getTranslateInstance( _x ,_y );
		// 使用_w，_h作为新图像的宽高
		BufferedImage dstImage = new BufferedImage( _w, _h, image.getType() );
		// 无图像部分填充颜色
		Graphics2D biContext = dstImage.createGraphics();
		biContext.setColor( new Color( color[0], color[1], color[2] ) );
		biContext.fillRect( 0 ,0 ,_w ,_h );
		biContext.drawImage( dstImage ,0 ,0 ,null );
		// 旋转
		affineTransform.rotate( java.lang.Math.toRadians( 360 - angle ) );
		AffineTransformOp affineTransformOp = new AffineTransformOp( affineTransform, 1 );
		return affineTransformOp.filter( image ,dstImage );
	}

	/** 
	 * 从原图获取缩略图
	 * @param thumbnail
	 */
	public static String getThumbnailFormImage(String thumbnail)
	{
		String s = thumbnail.substring( 0 ,thumbnail.lastIndexOf( '.' ) );
		return s + ".thumb.jpg";
	}

	/** 
	 * 生成缩略图(新图片名称是原图片名称 + .thumb.jpg )
	 * @param file 原图名称
	 * @param width
	 * @param height
	 */
	public static void thumbnail(String file, int width, int height)
	{
		File srcFile = new File( file );
		String name = srcFile.getPath();
		name = name.substring( 0 ,name.lastIndexOf( "." ) );
		File disFile = new File( name + ".thumb.jpg" );
		zoom( srcFile ,disFile ,"jpg" ,width ,height );
	}

	/** 
	 * 缩放图片
	 * @param srcFile 原始图像文件
	 * @param disFile 缩略图像文件
	 * @param format 缩略图格式(jpg gif png )
	 * @param width 缩略图宽度
	 * @param height 缩略图高度
	 */
	public static void zoom(String srcFile, String disFile, String format, int width, int height)
	{
		zoom( new File( srcFile ) ,new File( disFile ) ,format ,width ,height );
	}

	/** 
	 * 缩放图片
	 * @param file 原始图像文件(新的图片会覆盖原图)
	 * @param format 缩略图格式(jpg gif png )
	 * @param width 缩略图宽度
	 * @param height 缩略图高度
	 */
	public static void zoom(File srcfile, File disfile, String format, int width, int height)
	{
		double ratio = 0.0;
		try
		{
			BufferedImage bufferImage = ImageIO.read( srcfile );
			if ( width >= bufferImage.getWidth() && height >= bufferImage.getHeight() ) return;
			Image image = bufferImage.getScaledInstance( width ,height ,bufferImage.SCALE_SMOOTH );
			if ( (bufferImage.getHeight() > height) || (bufferImage.getWidth() > width) )
			{
				if ( bufferImage.getHeight() > bufferImage.getWidth() ) ratio = ((double) height) / bufferImage.getHeight();
				else ratio = ((double) width) / bufferImage.getWidth();
			}
			AffineTransformOp op = new AffineTransformOp( AffineTransform.getScaleInstance( ratio ,ratio ), null );
			image = op.filter( bufferImage ,null );
			ImageIO.write( (BufferedImage) image ,format ,disfile );
		}
		catch ( IOException e )
		{
			e.printStackTrace();
		}
	}

	/** 
	 * 添加文字水印
	 * 
	 * @param target
	 * 目标图片路径
	 * @param text
	 * 水印文字
	 * @param font
	 * 字体
	 * @param color
	 * 字体颜色
	 * @param position 图片定位
	 * @param alpha
	 * 透明度(0.0 -- 1.0, 0.0为完全透明，1.0为完全不透明)
	 */
	public static void markText(File target, String text, Font font, Color color, Position position, float alpha)
	{
		try
		{
			Image image = ImageIO.read( target );
			int width = image.getWidth( null );
			int height = image.getHeight( null );
			BufferedImage bufferedImage = new BufferedImage( width, height, BufferedImage.TYPE_INT_RGB );
			Graphics2D graphics = bufferedImage.createGraphics();
			graphics.drawImage( image ,0 ,0 ,width ,height ,null );
			if ( font != null )
			{
				graphics.setFont( font );
			};
			if ( color != null )
			{
				graphics.setColor( color );
			};
			graphics.setComposite( AlphaComposite.getInstance( AlphaComposite.SRC_ATOP ,alpha ) );
			int fontSize = graphics.getFont().getSize();
			int width_1 = fontSize * getLength( text );
			int height_1 = fontSize;
			int widthDiff = width - width_1;
			int heightDiff = height - height_1;
			position.calculate( widthDiff ,heightDiff );
			graphics.drawString( text ,position.getX() ,position.getY() + height_1 );
			graphics.dispose();
			ImageIO.write( bufferedImage ,"JPG" ,target );
		}
		catch ( Exception e )
		{
			e.printStackTrace();
		}
	}

	/** 
	 * 获取字符长度，一个汉字作为 1 个字符, 一个英文字母作为 0.5 个字符
	 * 
	 * @param text
	 * @return 字符长度，如：text="中国",返回 2；text="test",返回 2；text="中国ABC",返回 4.
	 */
	public static int getLength(String text)
	{
		int textLength = text.length();
		int length = textLength;
		for ( int i = 0 ; i < textLength ; i++ )
		{
			if ( String.valueOf( text.charAt( i ) ).getBytes().length > 1 )
			{
				length++;
			}
		}
		return (length % 2 == 0) ? length / 2 : length / 2 + 1;
	}

	/**
	 * 图片定位
	 * 
	 * @author THINK
	 * 
	 */
	public interface Position
	{

		public int getX();

		public int getY();

		public void calculate(int width, int height);

		enum Kind
		{
			/** 
			 * 绝对定位
			 */
			ABSOLUTE,
			/** 
			 * 相对定位
			 */
			RELATIVE;
		}
	}

	/**
	 * 相对对定位
	 * 
	 * @author THINK
	 * 
	 */
	public static class Relative implements Position
	{

		private int	x;

		private int	y;

		public Relative(int x, int y)
		{
			this.x = x;
			this.y = y;
		}

		@Override
		public int getX()
		{
			return x;
		}

		@Override
		public int getY()
		{
			return y;
		}

		public void calculate(int width, int height)
		{
			x = width - x;
			if ( x < 0 )
			{
				x = 0;
			}
			y = height - y;
			if ( y < 0 )
			{
				y = 0;
			}
		}
	}

	/**
	 * 绝对定位
	 * 
	 * @author THINK
	 * 
	 */
	public static class Absolute implements Position
	{

		private int	x;

		private int	y;

		public Absolute(int x, int y)
		{
			this.x = x;
			this.y = y;
		}

		@Override
		public int getX()
		{
			return x;
		}

		@Override
		public int getY()
		{
			return y;
		}

		public void calculate(int width, int height)
		{
			;
		}
	}

	public static class NamePosition implements Position
	{

		private X	xname;

		private Y	yname;

		private int	x;

		private int	y;

		public NamePosition(X x, Y y)
		{
			this.xname = x;
			this.yname = y;
		}

		@Override
		public int getX()
		{
			return x;
		}

		@Override
		public int getY()
		{
			return y;
		}

		@Override
		public void calculate(int width, int height)
		{
			switch ( xname )
			{
				case LEFT :
					x = 0;
					break;
				case RIGHT :
					x = width;
					break;
				case CENTER :
					x = width / 2;
					break;
			}
			switch ( yname )
			{
				case TOP :
					y = 0;
					break;
				case BOTTOM :
					y = height;
					break;
				case MIDDLE :
					y = height / 2;
					break;
			}
		}

		public enum X
		{
			LEFT,
			RIGHT,
			CENTER;
		}

		public enum Y
		{
			TOP,
			BOTTOM,
			MIDDLE;
		}
	}
}
/* Honey v3.1 Test - version:1 - OriginalChecksum:B775818be7aed159f5c041f507573cec6 (do not edit this line) */
